package cn.wolfcode.rbac.service.impl;

import cn.wolfcode.rbac.domain.Employee;
import cn.wolfcode.rbac.domain.Role;
import cn.wolfcode.rbac.mapper.EmployeeMapper;
import cn.wolfcode.rbac.mapper.PermissionMapper;
import cn.wolfcode.rbac.mapper.RoleMapper;
import cn.wolfcode.rbac.qo.QueryObject;
import cn.wolfcode.rbac.service.IRoleService;
import cn.wolfcode.rbac.web.exception.BusinessException;
import cn.wolfcode.rbac.web.vo.RolePermissionVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import static cn.wolfcode.rbac.common.RedisKeyPrefix.CACHE_PREFIX;

/**
 * 角色业务
 */
@Service
@Transactional
public class RoleServiceImpl implements IRoleService {

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Override
    public PageInfo<Role> list(QueryObject qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        List<Role> roles = roleMapper.selectAll();
        return new PageInfo(roles);
    }

    @Override
    public void deleteRoleById(Long id) {
        //删除角色，注意：判断员工是否有关联该角色,根据角色id查询员工id
        List<Long> employeeIds = roleMapper.selectEmployeeIdByRoleId(id);
        if(!employeeIds.isEmpty()){
            throw new BusinessException("角色删除失败,该角色有关联的员工");
        }

        int result = roleMapper.deleteByPrimaryKey(id);
        if (result == 0) {
            throw new BusinessException("角色删除失败");
        }
    }

    @Override
    public Role get(Long id) {
        Role role = roleMapper.selectByPrimaryKey(id);
        if (role == null) {
            throw new BusinessException("不存在该角色");
        }
        return role;
    }


    @Override
    public List<Role> query(Long id) {
        //判断是否是超级管理员
        Employee employee = new Employee();
        employee.setId(id);
        Employee employeeInfo = employeeMapper.selectByEmployeeInfo(employee);
        if(employeeInfo.getAdmin()){
            return null;
        }
        //不是超级管理员,再查询是什么角色
        List<Role> roles = roleMapper.selectRoleByEmployeeId(id);
        return roles;
    }

    @Override
    public void save(RolePermissionVo rolePermissionVo) {
        //保存角色
        Role role = rolePermissionVo.getRole();
        int roleSaveResult = roleMapper.insert(role);
        if (roleSaveResult == 0) {
            throw new BusinessException("角色保存失败");
        }
        //维护角色和权限的关系,根据角色的id维护权限的id的关系
        Long roleId = role.getId();
        List<Long> permissionIds = rolePermissionVo.getPermissionIds();
        //判断是否有权限
        if(permissionIds.isEmpty()){
            return;
        }
        //问题：此时，如果用遍历的方式去插入数据，则是有多少条数据，则发多少个请求
//        permissionIds.forEach(permissionId -> {
//            permissionMapper.insertRoleIdAndPermissionId(roleId, permissionId);
//        });
        //优化方案：只需要发一次请求，在mybatis中用<foreach>动态标签插入即可
        permissionMapper.insertRoleIdAndPermissionId(roleId,permissionIds);
    }

    @Override
    public void update(RolePermissionVo rolePermissionVo) {
        //更新角色
        Role role = rolePermissionVo.getRole();

        int roleUpdateResult = roleMapper.updateByPrimaryKey(role);
        if (roleUpdateResult == 0) {
            throw new BusinessException("角色更新失败");
        }
        //维护角色和权限的关系
        //根据角色id删除所有权限信息
        Long roleId = role.getId();
        permissionMapper.deletePermissionIdByRoleId(roleId);
        List<Long> permissionIds = rolePermissionVo.getPermissionIds();
        //保存角色和权限的关系
        //问题：此时，如果用遍历的方式去插入数据，则是有多少条数据，则发多少个请求
//        permissionIds.forEach(permissionId -> {
//            permissionMapper.insertRoleIdAndPermissionId(roleId, permissionId);
//        });
        //优化方案：只需要发一次请求，在mybatis中用<foreach>动态标签插入即可
        permissionMapper.insertRoleIdAndPermissionId(roleId,permissionIds);
    }
}
